package com.pushmessgae.server;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import com.pushmessgae.server.config.ConstValue;
import com.pushmessgae.server.log.Log;
import com.pushmessgae.server.util.SocketUtil;

public class ClientThread implements Runnable, SendDataAble {

	private static final String TAG = ClientThread.class.getSimpleName();

	private Socket socket;

	private InputListener inputListener;
	
	private ErrorInputListener errorInputListener;

	private boolean flag;

	/**
	 * 
	 */
	private String clientInfo;

	public ClientThread(Socket socket) {
		this.socket = socket;
	}

	/**
	 * 每一个客户端建立一个线程
	 */
	public void start() {
		if (null == socket)
			return;
		clientInfo = SocketUtil.getSocketAddress(socket);
		Log.d(TAG, "客户端建立一个线程" + clientInfo);
		flag = true;
		new Thread(this).start();
	}

	@Override
	public void run() {
		int maxtry = 5;
		while (flag) {
			try {
				if (maxtry == 0){
					errorInputListener.errorInput(this);
					break;
				}
				byte[] outBytes = read();
				if (0 == outBytes.length) {
					maxtry--;
					continue;
				}
				Log.d(TAG, "收到来自客户端" + clientInfo + "的数据 大小:" + outBytes.length);
				nofiyInputListener(outBytes);
			} catch (IOException e) {
				Log.d(TAG, "读取发生错误!");
				e.printStackTrace();
				maxtry--;
			}
		}
		Log.d(TAG, clientInfo + "客户端退出...");
	}

	private void nofiyInputListener(byte[] bs) throws IOException {
		if (null != inputListener) {
			inputListener.receive(bs);
		}
	}

	public byte[] read() throws IOException {
		final ByteArrayOutputStream out = new ByteArrayOutputStream();
		final InputStream in = socket.getInputStream();
		int len = 0;
		int available = 0;
		byte[] bs = new byte[ConstValue.READ_MAX];
		while (-1 != (len = in.read(bs))) {
			out.write(bs, 0, len);
			available = in.available();
			if (available == 0)
				break;
		}
		out.flush();
		out.close();
		return out.toByteArray();
	}

	@Override
	public boolean send(DataInputStream in) throws IOException {
		final OutputStream out = socket.getOutputStream();
		int len = 0;
		int available = 0;
		do {
			byte[] bs = new byte[ConstValue.READ_MAX];
			len = in.read(bs);
			available = in.available();
			out.write(bs, 0, len);
		} while (len != -1 && available > 0);
		out.flush();
		return true;
	}

	public void setInputListener(InputListener inputListener) {
		this.inputListener = inputListener;
	}

	public void setErrorInputListener(ErrorInputListener errorInputListener) {
		this.errorInputListener = errorInputListener;
	}

	public Socket getSocket() {
		return socket;
	}

	public String getClientInfo() {
		return clientInfo;
	}

	public String getAddress() {
		return socket.getInetAddress().getHostAddress();
	}

	public String getPort() {
		return "" + socket.getPort();
	}
}
